package com.xzzz.irda.guardcat.server.app;

import cn.hutool.core.util.RandomUtil;
import com.xzzz.common.base.pojo.R;
import com.xzzz.common.base.util.BeanUtil;
import com.xzzz.irda.guardcat.server.app.pojo.AppRelationVO;
import com.xzzz.irda.guardcat.server.repos.memory.AppRelationRepositoryInMemory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 【Server】应用调用关系
 */
@Slf4j
@RestController
@RequestMapping("/guardcat")
public class GuardcatAppRelationController {
    @Autowired
    private AppManager appManager;
    @Autowired
    private AppRelationRepositoryInMemory relationRepository;

    /**
     * 最大 mock 的应用个数
     */
    private static final int MAX_MOCK_APP_COUNT = 20;

    /**
     * 获取应用调用关系
     *
     * @return 应用列表和应用关系
     */
    @GetMapping("/app/relation")
    public R<Map<String, Object>> getRelation(@RequestParam(required = false) Boolean mock) {
        log.debug("查询应用调用关系");
        Map<String, Object> map = new HashMap<>(2);
        map.put("apps", appManager.getAppNames().stream().map(String::toLowerCase).collect(Collectors.toList()));
        map.put("links", relationRepository.refresh());

        if (mock == null) {
            mock = true;
        }
        // mock 数据
        if (mock) {


            List<String> apps = (List<String>) map.get("apps");
            if (apps == null) {
                apps = new ArrayList<>();
            }

            // 随机应用数量, 最大30个应用
            int appCount = RandomUtil.randomInt(8, MAX_MOCK_APP_COUNT - apps.size());
            for (int i = 1; i < appCount; i++) {
                apps.add("demo" + i);
            }
            map.put("apps", apps);

            Set<AppRelationVO> links = (Set<AppRelationVO>) map.get("links");
            if (links == null) {
                links = new HashSet<>();
            }

            // 将网关与所有应用相连
            for (String app : apps) {
                AppRelationVO gatewayRelation = new AppRelationVO()
                        .setSource("expand-gateway")
                        .setTarget(app)
                        .setType("gateway").setNum(1);
                links.add(gatewayRelation);
            }

            // 随机构造应用调用关系
            for (int i = 0; i < appCount * 3; i++) {
                String source = apps.get(RandomUtil.randomInt(0, apps.size() - 1));
                String target = apps.stream().filter(app -> !"expand-gateway".equals(app)).collect(Collectors.toList()).get(RandomUtil.randomInt(0, apps.size() - 1));
                String type = "feign";

                AppRelationVO appRelationVO = new AppRelationVO().setSource(source).setTarget(target).setType(type).setNum(1);
                links.add(appRelationVO);

                // 每次都有1/3的概率生成MQ关系
                if (RandomUtil.randomInt(0, 3) == 1) {
                    AppRelationVO mqRelation = BeanUtil.toObj(appRelationVO, AppRelationVO.class);
                    mqRelation.setType("rocketmq").setValue("test_topic").setNum(3);
                    links.add(mqRelation);
                }
            }

            map.put("links", links);
        }
        return R.ok(map);
    }

}
